package com.keqiang.huaweiscan;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import com.hjq.permissions.*;
import com.huawei.hms.hmsscankit.RemoteView;
import com.huawei.hms.hmsscankit.ScanUtil;
import com.huawei.hms.ml.scan.HmsScan;
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle.State;
import me.zhouzhuo810.magpiex.ui.act.BaseActivity;
import me.zhouzhuo810.magpiex.ui.dialog.TwoBtnTextDialog;
import me.zhouzhuo810.magpiex.utils.SimpleUtil;
import me.zhouzhuo810.magpiex.utils.ToastUtil;

/**
 * 华为扫码界面
 *
 * @author Created by wanggaowan on 2021/10/26 16:56
 */
public class HuaWeiScanActivity extends BaseActivity {
    
    /**
     * 扫码配置数据
     */
    public static final String SCAN_CONFIG = "scanConfig";
    
    /**
     * 扫码是否取消
     */
    public static final String SCAN_CANCEL = "scanCancel";
    
    /**
     * 是否扫描图片
     */
    public static final String SCAN_IMG = "scanImg";
    
    /**
     * 扫码结果
     */
    public static final String SCAN_RESULT = "scanResult";
    
    private static final int REQUEST_CODE_PHOTO = 0x1113;
    
    private RemoteView remoteView;
    private View mBackBtn;
    private View mAlbumBtn;
    private View mVScanLine;
    private ImageView mIvLight;
    
    private ObjectAnimator mTranslationY;
    
    private ScanConfig mScanConfig;
    private boolean manualTrunLight;
    
    @Override
    public void initView(@Nullable Bundle savedInstanceState) {
        mScanConfig = getIntent().getParcelableExtra(SCAN_CONFIG);
        if (mScanConfig == null) {
            closeAct();
            return;
        }
        
        mBackBtn = findViewById(R.id.back_btn);
        mAlbumBtn = findViewById(R.id.album_btn);
        mVScanLine = findViewById(R.id.v_scan_line);
        mIvLight = findViewById(R.id.iv_light);
        FrameLayout frameLayout = findViewById(R.id.rim);
        TextView tvTitle = findViewById(R.id.tv_title);
        TextView tvHint = findViewById(R.id.tv_hint);
        View appBar = findViewById(R.id.anchor4);
        
        if (!mScanConfig.isCouldScanImg()) {
            mAlbumBtn.setVisibility(View.GONE);
        }
        
        if (mScanConfig.getTitle() != null) {
            tvTitle.setText(mScanConfig.getTitle());
        }
        
        if (mScanConfig.getScanLineColor() != -1) {
            mVScanLine.setBackgroundColor(mScanConfig.getScanLineColor());
        }
        
        if (mScanConfig.getAppBarColor() != -1) {
            appBar.setBackgroundColor(mScanConfig.getAppBarColor());
        }
        
        if (mScanConfig.isShowLightButton()) {
            mIvLight.setVisibility(View.VISIBLE);
        }
        
        frameLayout.post(() -> init(frameLayout, tvHint));
    }
    
    @Override
    public int getLayoutId() {
        return R.layout.activity_huawei_scan;
    }
    
    @Override
    public void initData() {
    
    }
    
    @Override
    public void initEvent() {
        String permission = getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.TIRAMISU
            ? Permission.READ_MEDIA_IMAGES : Permission.READ_EXTERNAL_STORAGE;
        mAlbumBtn.setOnClickListener(v -> {
            XXPermissions permissions = XXPermissions.with(this).permission(permission);
            if (!TextUtils.isEmpty(mScanConfig.getApplyAlbumPermissionHint())) {
                permissions.interceptor(new IPermissionInterceptor() {
                    @Override
                    public void launchPermissionRequest(@NonNull Activity activity, @NonNull List<String> allPermissions, @Nullable OnPermissionCallback callback) {
                        IPermissionInterceptor thisInterceptor = this;
                        showTwoBtnTextDialog("", mScanConfig.getApplyAlbumPermissionHint(), new TwoBtnTextDialog.OnTwoBtnTextClick() {
                            @Override
                            public void onLeftClick(TextView v) {
                            
                            }
                            
                            @Override
                            public void onRightClick(TextView v) {
                                PermissionFragment.launch(
                                    activity,
                                    new ArrayList<>(allPermissions),
                                    thisInterceptor,
                                    callback
                                );
                            }
                        });
                    }
                });
            }
            permissions.request((list, all) -> {
                Intent pickIntent = new Intent(Intent.ACTION_PICK,
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActWithIntentForResult(pickIntent, REQUEST_CODE_PHOTO);
            });
        });
        
        mIvLight.setOnClickListener(view -> {
            manualTrunLight = true;
            boolean lightStatus = remoteView.getLightStatus();
            remoteView.switchLight();
            mIvLight.setImageResource(lightStatus ? R.drawable.ic_sgdguan : R.drawable.ic_sgdkai);
        });
        
        mBackBtn.setOnClickListener(v -> closeAct());
    }
    
    @Override
    public boolean shouldSupportMultiLanguage() {
        return false;
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        if (remoteView != null)
            remoteView.onStart();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        if (remoteView != null) {
            remoteView.onResume();
            startScanAnim();
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (remoteView != null) {
            remoteView.onPause();
            endScanAnim();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (remoteView != null)
            remoteView.onDestroy();
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if (remoteView != null)
            remoteView.onStop();
    }
    
    /**
     * Handle the return results from the album.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == REQUEST_CODE_PHOTO) {
            try {
                InputStream inputStream = getContentResolver().openInputStream(data.getData());
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                inputStream.close();
                HmsScan[] hmsScans = ScanUtil.decodeWithBitmap(this, bitmap,
                    new HmsScanAnalyzerOptions.Creator().setPhotoMode(true).create());
                if (hmsScans != null && hmsScans.length > 0 && hmsScans[0] != null
                    && hmsScans[0].getOriginalValue() != null) {
                    HmsScan hmsScan = hmsScans[0];
                    Intent intent = new Intent();
                    intent.putExtra(SCAN_CANCEL, false);
                    intent.putExtra(SCAN_IMG, true);
                    intent.putExtra(SCAN_RESULT, hmsScan);
                    setResult(RESULT_OK, intent);
                    closeAct();
                } else {
                    imgScanFailed();
                }
            } catch (IOException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
                imgScanFailed();
            }
        }
    }
    
    private void imgScanFailed() {
        if (mScanConfig.isImgScanFailedBack()) {
            Intent intent = new Intent();
            intent.putExtra(SCAN_CANCEL, false);
            intent.putExtra(SCAN_IMG, true);
            setResult(RESULT_OK, intent);
            closeAct();
            return;
        }
        
        if (mScanConfig.getImgScanFailedHint() != null) {
            ToastUtil.showToast(mScanConfig.getImgScanFailedHint());
            return;
        }
        
        ToastUtil.showToast(getString(R.string.image_scan_error_hint));
    }
    
    private void init(FrameLayout root, TextView tvHint) {
        int screenWidth = getResources().getDisplayMetrics().widthPixels;
        int screenHeight = getResources().getDisplayMetrics().heightPixels;
        
        // 界面展示的识别区域大小
        int scanFrameSize = SimpleUtil.getScaledValue(950);
        // 实际识别区域扩大offset范围
        int offset = SimpleUtil.getScaledValue(50);
        // 配置识别区域位置
        Rect rect = new Rect();
        rect.left = screenWidth / 2 - scanFrameSize / 2 - offset;
        rect.right = screenWidth / 2 + scanFrameSize / 2 + offset;
        rect.top = screenHeight / 2 - scanFrameSize / 2 - offset;
        rect.bottom = screenHeight / 2 + scanFrameSize / 2 + offset;
        remoteView = new RemoteView.Builder()
            .setContext(this)
            .setBoundingBox(rect)
            .setFormat(mScanConfig.getFormat(), mScanConfig.getFormats())
            // 是否循环扫码
            .setContinuouslyScan(false)
            .build();
        
        remoteView.onCreate(null);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        root.addView(remoteView, params);
        
        remoteView.setOnResultCallback(result -> {
            if (result != null && result.length > 0 && result[0] != null && result[0].getOriginalValue() != null) {
                HmsScan hmsScan = result[0];
                Intent intent = new Intent();
                intent.putExtra(SCAN_CANCEL, false);
                intent.putExtra(SCAN_RESULT, hmsScan);
                setResult(RESULT_OK, intent);
                closeAct();
            }
        });
        
        State state = getLifecycle().getCurrentState();
        if (state.isAtLeast(State.STARTED)) {
            remoteView.onStart();
        }
        
        if (state.isAtLeast(State.RESUMED)) {
            remoteView.onResume();
            startScanAnim();
        }
        
        if (mScanConfig.getHint() != null) {
            tvHint.setText(mScanConfig.getHint());
        } else {
            tvHint.setText(getString(R.string.scan_code_hint));
        }
        
        if (mScanConfig.isTurnOnLight()) {
            openLight();
        }
    }
    
    private void openLight() {
        remoteView.postDelayed(() -> {
            if (!manualTrunLight && !remoteView.getLightStatus()) {
                remoteView.switchLight();
                openLight();
            } else {
                mIvLight.setImageResource(remoteView.getLightStatus() ? R.drawable.ic_sgdkai : R.drawable.ic_sgdguan);
            }
        }, 200);
    }
    
    private void startScanAnim() {
        if (mTranslationY != null && mTranslationY.isStarted()) {
            return;
        }
        
        mTranslationY = ObjectAnimator.ofFloat(mVScanLine, "translationY", 0, SimpleUtil.getScaledValue(945));
        mTranslationY.setDuration(3000);
        mVScanLine.setVisibility(View.VISIBLE);
        mTranslationY.setRepeatCount(ValueAnimator.INFINITE);
        mTranslationY.start();
    }
    
    private void endScanAnim() {
        mVScanLine.setVisibility(View.GONE);
        if (mTranslationY != null && mTranslationY.isRunning()) {
            mTranslationY.end();
        }
    }
}
